<template>
  <div class="wechat-modal">
    <BasicModal
      to=".wechat-modal"
      class="w-[420px]"
      :mask-closable="false"
      @register="wxLoginModalRegister"
      @after-leave="afterLeave"
    >
      <n-card class="wechat-card" :bordered="false">
        <n-text class="text-base">微信扫码登录</n-text>
        <n-text class="text-base">首次扫码授权后将自动完成注册</n-text>
        <n-spin class="qrcode-spin" :show="state.qrcodeLoading">
          <div v-if="!state.url && !state.qrcodeLoading" class="qrcode-expired">
            <n-text class="text-white/80">二维码已失效</n-text>
            <n-button type="primary" @click="getQrcode">刷新</n-button>
          </div>
          <qrcode-vue
            class="mt-4 border rounded"
            :value="state.url"
            render-as="svg"
            :margin="2"
            :size="240"
            level="L"
          />
        </n-spin>
      </n-card>
      <template #action>
        <div></div>
      </template>
    </BasicModal>
  </div>
</template>

<script setup>
import { defineAsyncComponent, reactive } from 'vue'
import { useUserStore, useChatStore } from '@/store'
import { useRoute, useRouter } from 'vue-router'
import QrcodeVue from 'qrcode.vue'
import { useModal } from '@cmps/Modal/useModal'
import { checkWxLogin } from '@api/userApi'
import { baseURL } from '@/axios'
import { isWeiXin, createId } from '@/utils'

const BasicModal = defineAsyncComponent(() => import('@cmps/Modal/BasicModal.vue'))

const route = useRoute()
const router = useRouter()

const userStore = useUserStore()
const chatStore = useChatStore()

const state = reactive({
  qrcodeLoading: false,
  url: '',
  login_id: route.query.login_id || null,
  checkLoginTimer: null,
  second: 0,
})

const emit = defineEmits(['register'])

const { VITE_APP_TITLE, VITE_APP_WX_OPEN_URL } = import.meta.env

const [wxLoginModalRegister, { openModal: basicOpenWxModal, closeModal: basicCloseWxModal }] = useModal({
  title: VITE_APP_TITLE,
})

const getQrcode = () => {
  try {
    state.second = 0
    state.qrcodeLoading = true
    state.login_id = createId()
    const ref = localStorage.getItem('ref')
    const url = `${location.origin}/wxlogin?login_id=${state.login_id}`
    state.url = ref ? url + `&ref=${ref}` : url
    state.checkLoginTimer = setInterval(checkLogin, 2000)
  } finally {
    state.qrcodeLoading = false
  }
}

const checkLogin = async () => {
  try {
    state.second += 2
    const res = await checkWxLogin({ login_id: state.login_id })
    if (res.statusCode === 200) {
      if (res.login_state === 1) {
        chatStore.isNewChat = true
        basicCloseWxModal()
        userStore.setUserState({ token: res.user_token })
        await userStore.getUserInfo().then(async res => {
          if (res.statusCode === 200) {
            await chatStore.getMsgList()
            localStorage.removeItem('ref')
            $message.destroyAll()
            $message.success('登录成功')
          }
        })
      }
    }
  } finally {
    if (state.second >= 60) {
      afterLeave()
    }
    router.replace({ query: {} })
  }
}
if (route.query.login_id) {
  checkLogin()
}

const afterLeave = () => {
  state.url = ''
  state.second = 0
  clearInterval(state.checkLoginTimer)
  state.checkLoginTimer = null
}

const openWxLogin = () => {
  if (isWeiXin()) {
    const redirectUri = encodeURIComponent(`${baseURL}/auth/getWxAccessToken`)
    const state = window.btoa(
      JSON.stringify({
        i: createId(),
        u: location.href,
        v: localStorage.getItem('ref') || undefined,
      })
    )
    location.replace(
      `${VITE_APP_WX_OPEN_URL}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`
    )
    return
  }
  basicOpenWxModal()
  getQrcode()
}

defineExpose({
  openWxLogin,
})
</script>

<style lang="less" scoped>
.wechat-modal {
  &:deep(.n-dialog__content) {
    margin-top: 12px;

    .wechat-card {
      .n-card__content {
        padding: 14px 0 0;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;

        .qrcode-spin {
          .n-spin-content {
            position: relative;

            .qrcode-expired {
              width: 100%;
              height: 100%;
              position: absolute;
              z-index: 10;
              left: 0;
              top: 0;
              display: flex;
              align-items: center;
              justify-content: center;
              flex-direction: column;
              gap: 10px;
              backdrop-filter: saturate(150%) contrast(50%) blur(8px);
              -webkit-backdrop-filter: saturate(150%) contrast(50%) blur(8px);
              background-color: rgba(0, 0, 0, 0.3);
            }
          }
        }
      }
    }
  }
}
</style>
